#include "stdafx.h"
#include "catalog.h"
#include <boost/extension/shared_library.hpp>
#include "nef_register.h"

using namespace nef;
using namespace boost::extensions;

Catalog::Ptr Catalog::s_statalog = Catalog::Ptr(new Catalog);

Catalog::Ptr Catalog::GlobalCatalog()
{
	return s_statalog;
}

nef::Catalog::Catalog()
{

}

nef::Catalog::Ptr nef::Catalog::Create()
{
	return Ptr(new Catalog);
}

void nef::Catalog::LoadFolder( const fs::path &p )
{
	LoadComponentsInternal(p);

	Init();
}

bool nef::Catalog::LoadAssembly( const fs::path &p )
{
	if (!LoadAssemblyInternal(p))
		return false;

	Init();

	return true;
}

void nef::Catalog::AddEntryPoint( nef_entry_point_function ex )
{
	_entryPoints.push_back(ex);
}

void nef::Catalog::Init()
{
	for (auto ep : _entryPoints)
		ep(_exports);

	_entryPoints.clear();

	if (this != s_statalog.get())
		s_statalog->Init();
}

void nef::Catalog::LoadComponentsInternal( const fs::path &p )
{
	fs::recursive_directory_iterator end_itr;
	for (fs::recursive_directory_iterator iter(p); iter != end_itr; ++iter)
		LoadAssemblyInternal(iter->path());
}

bool nef::Catalog::LoadAssemblyInternal( const fs::path &p )
{
	if (!fs::exists(p) || p.extension() != ".dll")
		return false;

	nef_out << "Loading Module: " << p << " ... ";

	shared_library lib(p.string());

	//nef_entry_point_function fn = lib.get<void, std::vector<IExport::Ptr> &>(NEF_ENTRY_POINT_NAME_S);

	// TODO: Check to see if this succeeds
	bool success = lib.open();
	if (success)
		nef_out << "Success!!!" << nef_line;
	else
		nef_out << "Failed :(" << nef_line;

	return success;
}






